#![allow(non_camel_case_types)]
#![allow(dead_code)]
#![allow(non_snake_case)]
use crate::*;

// interface ArrayLike<T> {
//     readonly length: number;
//     readonly [n: number]: T;
// }
pub trait ArrayLike<'val, T>: InterFace<'val> {
	fn g_length(&self) -> number<'val>;
	fn i_index(&self, index: number<'val>) -> T;
}

// interface Iterable<T> {
//     [Symbol.iterator](): Iterator<T>;
// }
pub trait Iterable<'val, T>: InterFace<'val> {
	fn s_iterator(&self) -> impl Iterator<'val, T>;
}

// interface IteratorYieldResult<TYield> {
//     done?: false;
//     value: TYield;
// }
pub trait IteratorYieldResult<'val, T>: InterFace<'val> {
	fn g_done(&self) -> Option<bool>;
	fn g_value(&self) -> T;
}

// interface IteratorReturnResult<TReturn> {
//     done: true;
//     value: TReturn;
// }
pub trait IteratorReturnResult<'val, T>: InterFace<'val> {
	fn g_done(&self) -> Option<bool>;
	fn g_value(&self) -> T;
}

// type IteratorResult<T, TReturn = any> = IteratorYieldResult<T> | IteratorReturnResult<TReturn>;
pub enum IteratorResult<'val, T, TReturn> {
	Yield(&'val dyn IteratorYieldResult<'val, T>),
	Return(&'val dyn IteratorReturnResult<'val, TReturn>),
}

// interface Iterator<T, TReturn = any, TNext = undefined> {
//     // NOTE: 'next' is defined using a tuple to ensure we report the correct assignability errors in all places.
//     next(...args: [] | [TNext]): IteratorResult<T, TReturn>;
//     return?(value?: TReturn): IteratorResult<T, TReturn>;
//     throw?(e?: any): IteratorResult<T, TReturn>;
// }
pub trait Iterator<'val, T>: InterFace<'val> {
	fn next(&self, args: Option<Value<'_>>) -> IteratorResult<'val, T, Value<'_>>;
}
